package biz

import (
	"beetle/internal/model"
	"beetle/internal/pkg/constant"
	"errors"
	"gorm.io/gorm"
)

type DictService interface {
	Save(model *model.Dict) error
	Update(model *model.Dict) error
	Remove(id int) error
	Find(id int) (*model.Dict, error)
	Page(model *model.Dict, pager model.Pager) *model.Page
}

type DictRepo interface {
	Save(model *model.Dict) bool
	Update(model *model.Dict) bool
	Remove(id int) bool
	Find(id int) *model.Dict
	Count(model *model.Dict) int
	Page(model *model.Dict, pager model.Pager) []*model.Dict
}

type dictService struct {
	repo DictRepo
}

func NewDictService(repo DictRepo) *dictService {
	return &dictService{repo}
}

func (srv *dictService) Save(dict *model.Dict) error {

	if dict.Code == "" {
		return errors.New("Code参数名不能为空")
	}

	if dict.Name == "" {
		return errors.New("Name参数名不能为空")
	}

	success := srv.repo.Save(dict)
	if success {
		return nil
	}
	return errors.New("保存失败")

}

func (srv *dictService) Update(dict *model.Dict) error {

	if dict.ID == 0 {
		return errors.New("ID不能为空")
	}

	success := srv.repo.Update(dict)

	if success {
		return nil
	}

	return errors.New("更新失败")
}

func (srv *dictService) Remove(id int) error {

	success := srv.repo.Remove(id)

	if success {
		return nil
	}
	// TODO 记录日志
	return errors.New("删除失败")
}

func (srv *dictService) Find(id int) (*model.Dict, error) {

	if id == 0 {
		return nil, errors.New("ID不能为空")
	}

	setting := srv.repo.Find(id)

	if setting == nil {
		return nil, errors.New("未找到有效的配置信息")
	}

	return setting, nil
}

func (srv *dictService) Page(dict *model.Dict, pager model.Pager) *model.Page {

	count := srv.repo.Count(dict)

	records := srv.repo.Page(dict, pager)

	page := &model.Page{
		Total: count,
		List:  records,
	}

	return page
}

type dictRepo struct {
	db *gorm.DB
}

func NewDictRepo(db *gorm.DB) *dictRepo {
	return &dictRepo{db}
}

func (repo *dictRepo) Save(dict *model.Dict) bool {

	result := repo.db.Create(dict)

	if result.Error != nil {
		return false
	}

	return true
}

func (repo *dictRepo) Update(dict *model.Dict) bool {

	result := repo.db.Where("DEL_FLAG = ?", constant.UNDELETE).Updates(dict)

	if result.Error != nil {
		return false
	}

	return true
}

func (repo *dictRepo) Remove(id int) bool {

	result := repo.db.Model(&model.Dict{ID: id}).Update("DEL_FLAG", constant.DELETE)

	if result.Error != nil {
		return false
	}

	return true
}

func (repo *dictRepo) Find(id int) *model.Dict {

	var record model.Dict

	result := repo.db.Where("DEL_FLAG= ? AND ID = ? ", constant.UNDELETE, id).First(&record)

	if result.Error != nil {
		return nil
	}

	return &record
}

func (repo *dictRepo) Count(dict *model.Dict) int {

	var count int64
	tx := repo.dictPageCond(dict)
	tx.Count(&count)
	return int(count)
}

func (repo *dictRepo) Page(dict *model.Dict, pager model.Pager) []*model.Dict {

	var records []*model.Dict

	if pager.PageSize == 0 {
		pager.PageSize = 20
	}

	tx := repo.dictPageCond(dict)

	result := tx.Offset((pager.PageNum - 1) * pager.PageSize).Limit(pager.PageSize).Find(&records)
	if result.Error != nil {
		return nil
	}
	return records
}

func (repo *dictRepo) dictPageCond(dict *model.Dict) *gorm.DB {

	tx := repo.db.Model(&model.Dict{}).Where("DEL_FLAG = ? ", constant.UNDELETE)

	if dict.Code != "" {
		tx.Where("CODE LIKE ? ", "%"+dict.Code+"%")
	}

	if dict.Name != "" {
		tx.Where("NAME LIKE ? ", "%"+dict.Name+"%")
	}

	if dict.Pcode != "" {
		tx.Where("PCODE LIKE ? ", "%"+dict.Pcode+"%")
	}

	if dict.Scope != "" {
		tx.Where("SCOPE = ? ", dict.Scope)
	}

	if dict.Label != "" {
		tx.Where("LABEL = ? ", dict.Label)
	}

	tx.Order("LABEL DESC").Order("SEQ").Order("CREATE_TIME DESC")

	return tx
}
